﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Reflection;

namespace DataManager.TablesManager
{
    public class Manager
    {
        private string GetPrimaryKeyName<T>()
        {
            PropertyInfo[] infos = typeof(T).GetProperties();
            PropertyInfo PKProperty = null;
            foreach (PropertyInfo info in infos)
            {
                var column = info.GetCustomAttributes(false)
                 .Where(x => x.GetType() == typeof(ColumnAttribute))
                 .FirstOrDefault(x =>
                  ((ColumnAttribute)x).IsPrimaryKey &&
                  ((ColumnAttribute)x).DbType.Contains("NOT NULL"));
                if (column != null)
                {
                    PKProperty = info;
                    break;
                }
            }
            if (PKProperty == null)
            {
                throw new NotSupportedException(
                  typeof(T).ToString() + " has no Primary Key");
            }
            return PKProperty.Name;
        }

        public bool Insert<TEntity> (TEntity entity) where TEntity : class
        {
            try
            {
                DBDataContext db = new DBDataContext();
                db.GetTable(typeof(TEntity)).InsertOnSubmit(entity);
                db.SubmitChanges();
                return true;
            }
            catch (Exception ex)
            {
                Logs.Write(ex);
                return false;
            }
            
        }

        public TEntity SelectByID<TEntity>(string ID) where TEntity : class
        {
            try
            {
                Type type = typeof(TEntity);
                var att = type.GetCustomAttributes(typeof(TableAttribute), false).FirstOrDefault();
                string tablename = att == null ? "" : ((TableAttribute)att).Name;
                if (string.IsNullOrEmpty(tablename))
                    return null;
                else
                {
                    string query = string.Format("Select * from {0} where {1} = '{2}'", new object[] { tablename, GetPrimaryKeyName<TEntity>(), ID });
                    return new DBDataContext().ExecuteQuery<TEntity>(query).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Logs.Write(ex);
                throw ex;
            }
        }

        public List<TEntity> SelectSQL<TEntity>(string SQL) where TEntity : class
        {
            try
            {
                return new DBDataContext().ExecuteQuery<TEntity>(SQL).ToList<TEntity>();
            }
            catch (Exception ex)
            {
                Logs.Write(ex);
                throw ex;
            }
        }

        public List<TEntity> SelectAll<TEntity>() where TEntity : class
        {
            try
            {
                Type type = typeof(TEntity);
                var att = type.GetCustomAttributes(typeof(TableAttribute), false).FirstOrDefault();
                string tablename = att == null ? "" : ((TableAttribute)att).Name;
                if (string.IsNullOrEmpty(tablename))
                    return null;
                else
                {
                    string query = "SELECT * FROM " + tablename;
                    return new DBDataContext().ExecuteQuery<TEntity>(query).ToList<TEntity>();
                }
            }
            catch (Exception ex)
            {
                Logs.Write(ex);
                throw ex;
            }
        }

        public TEntity DeleteByID<TEntity>(string ID) where TEntity : class
        {
            try
            {
                Type type = typeof(TEntity);
                var att = type.GetCustomAttributes(typeof(TableAttribute), false).FirstOrDefault();
                string tablename = att == null ? "" : ((TableAttribute)att).Name;
                if (string.IsNullOrEmpty(tablename))
                    return null;
                else
                {
                    string query = string.Format("Delete {0} where {1} = '{2}'", new object[] { tablename, GetPrimaryKeyName<TEntity>(), ID });
                    return new DBDataContext().ExecuteQuery<TEntity>(query).FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                Logs.Write(ex);
                throw ex;
            }
        }
    }
}
